package serviceImpl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.persistence.Query;
import factoryService.FactoryService;
import model.ParcelaReceita;
import service.ParcelaReceitaService;

public class ParcelaReceitaServiceImpl extends
		GenericServiceImpl<ParcelaReceita> implements ParcelaReceitaService {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5817297386326354151L;

	private Query query;
	@SuppressWarnings("deprecation")
	public void fixoSemanal(ParcelaReceita parcelaReceita, int periodo) {
		ParcelaReceita parcela = parcelaReceita;
		if (periodo == 1) {
			for (int i = 1; i <= 13; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
			
		}

		if (periodo == 2) {
			for (int i = 1; i <= 26; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}

		if (periodo == 3) {
			for (int i = 1; i <= 52; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}

		if (periodo == 4) {
			for (int i = 1; i <= 104; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}

	}

	// ///

	@SuppressWarnings("deprecation")
	public void fixoMensal(ParcelaReceita parcelaReceita, int periodo) {
		ParcelaReceita parcela = parcelaReceita;
		if (periodo == 1) {
			for (int i = 1; i <= 3; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}

		if (periodo == 2) {
			for (int i = 1; i <= 6; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}

		if (periodo == 3) {
			for (int i = 1; i <= 12; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}

		if (periodo == 4) {
			for (int i = 1; i <= 24; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.MONTH, 1);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}
	}

	@SuppressWarnings("deprecation")
	public void fixoSemestral(ParcelaReceita parcelaReceita, int periodo) {
		ParcelaReceita parcela = parcelaReceita;
		if (periodo == 1) {
			FactoryService.getParcelaReceitaService().salvar(parcelaReceita);

		}

		if (periodo == 2) {
			FactoryService.getParcelaReceitaService().salvar(parcelaReceita);

		}

		if (periodo == 3) {
			for (int i = 1; i <= 2; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.MONTH, 6);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}

		if (periodo == 4) {
			for (int i = 1; i <= 4; i++) {
				FactoryService.getParcelaReceitaService().salvar(parcela);
				Calendar c = Calendar.getInstance();
				c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
				c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
				c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
				c.add(Calendar.MONTH, 6);
				parcela = new ParcelaReceita();
				parcela.setDataParcela(c.getTime());
				parcela.setReceita(parcelaReceita.getReceita());
				parcela.setUsuario(parcelaReceita.getUsuario());
				parcela.setValor(parcelaReceita.getValor());
			}
		}
	}

	@SuppressWarnings("deprecation")
	public void geraParcelaSemanal(ParcelaReceita parcelaReceita, int periodo2) {
		ParcelaReceita parcela = parcelaReceita;
		Float valor = (parcela.getValor() / periodo2);
		parcela.setValor(valor);
		for (int i = 1; i <= periodo2; i++) {
			parcela.setParcela(String.valueOf(i));
			FactoryService.getParcelaReceitaService().salvar(parcela);
			Calendar c = Calendar.getInstance();
			c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
			c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
			c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
			c.add(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
			parcela = new ParcelaReceita();
			parcela.setDataParcela(c.getTime());
			parcela.setReceita(parcelaReceita.getReceita());
			parcela.setUsuario(parcelaReceita.getUsuario());
			parcela.setValor(valor);
		}
	}

	
	@SuppressWarnings("deprecation")
	public void geraParcelaMensal(ParcelaReceita parcelaReceita, int periodo2) {
		ParcelaReceita parcela = parcelaReceita;
		Float valor = (parcela.getValor() / periodo2);
		parcela.setValor(valor);
		for (int i = 1; i <= periodo2; i++) {
			parcela.setParcela(String.valueOf(i));
			FactoryService.getParcelaReceitaService().salvar(parcela);
			Calendar c = Calendar.getInstance();
			c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
			c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
			c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
			c.add(Calendar.MONTH, 1);
			parcela = new ParcelaReceita();
			parcela.setDataParcela(c.getTime());
			parcela.setReceita(parcelaReceita.getReceita());
			parcela.setUsuario(parcelaReceita.getUsuario());
			parcela.setValor(valor);
		}
	}

	@SuppressWarnings("deprecation")
	public void geraParcelaSemestral(ParcelaReceita parcelaReceita, int periodo2) {
		ParcelaReceita parcela = parcelaReceita;
		Float valor = (parcela.getValor() / periodo2);
		parcela.setValor(valor);
		for (int i = 1; i <= periodo2; i++) {
			parcela.setParcela(String.valueOf(i));
			FactoryService.getParcelaReceitaService().salvar(parcela);
			Calendar c = Calendar.getInstance();
			c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
			c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
			c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
			c.add(Calendar.MONTH, 6);
			parcela = new ParcelaReceita();
			parcela.setDataParcela(c.getTime());
			parcela.setReceita(parcelaReceita.getReceita());
			parcela.setUsuario(parcelaReceita.getUsuario());
			parcela.setValor(valor);
		}
	}

	@SuppressWarnings("deprecation")
	public void geraParcelaAnual(ParcelaReceita parcelaReceita, int periodo2) {
		ParcelaReceita parcela = parcelaReceita;
		Float valor = (parcela.getValor() / periodo2);
		parcela.setValor(valor);
		for (int i = 1; i <= periodo2; i++) {
			parcela.setParcela(String.valueOf(i));
			FactoryService.getParcelaReceitaService().salvar(parcela);
			Calendar c = Calendar.getInstance();
			c.set(Calendar.DAY_OF_MONTH, parcela.getDataParcela().getDate());
			c.set(Calendar.MONTH, parcela.getDataParcela().getMonth());
			c.set(Calendar.YEAR, parcela.getDataParcela().getYear() + 1900);
			c.add(Calendar.YEAR, 1);
			parcela = new ParcelaReceita();
			parcela.setDataParcela(c.getTime());
			parcela.setReceita(parcelaReceita.getReceita());
			parcela.setUsuario(parcelaReceita.getUsuario());
			parcela.setValor(valor);
		}
	}
	
	@SuppressWarnings("deprecation")
	public Double resultParcelaReceitaEntreDatas(Date data, Long codigo) {
		Calendar cFim = Calendar.getInstance();
		Calendar cInicio = Calendar.getInstance();
		cFim.set(Calendar.DAY_OF_MONTH, data.getDate());
		cFim.set(Calendar.MONTH, data.getMonth());
		cFim.set(Calendar.YEAR, data.getYear() + 1900);
		cInicio.set(Calendar.DAY_OF_MONTH, data.getDate());
		cInicio.set(Calendar.MONTH, data.getMonth());
		cInicio.set(Calendar.YEAR, data.getYear() + 1900);
		cFim.set(Calendar.DAY_OF_MONTH, cFim.getActualMaximum(Calendar.DAY_OF_MONTH));
		cInicio.set(Calendar.DAY_OF_MONTH, cInicio.getActualMinimum(Calendar.DAY_OF_MONTH));

		query = getEm().createQuery(
				"Select sum(c.valor) from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim and c.compensado = 'Sim'");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", cInicio.getTime());
		query.setParameter("fim", cFim.getTime());
		return (Double) query.getSingleResult();
	}

	@SuppressWarnings({ "deprecation", "unchecked" })
	public List<ParcelaReceita> listaParcelaReceitaEntreDatas(Date data,Long codigo) {
		Calendar cFim = Calendar.getInstance();
		cFim.set(Calendar.DAY_OF_MONTH, data.getDate());
		cFim.set(Calendar.MONTH, data.getMonth());
		cFim.set(Calendar.YEAR, data.getYear() + 1900);
		cFim.add(Calendar.MONTH, 1);
		query = getEm().createQuery(
				"Select c from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim order by c.dataParcela");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", data);
		query.setParameter("fim", cFim.getTime());
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<ParcelaReceita> listaParcelaReceitaEntreDatasMovimentacoes(Integer mes,Integer ano, Long codigo) {
		Calendar cFim = Calendar.getInstance();
		Calendar cInicio = Calendar.getInstance();
		cInicio.set(Calendar.DAY_OF_MONTH, 1);
		cInicio.set(Calendar.MONTH, mes-1);
		cInicio.set(Calendar.YEAR, ano);
		cFim.set(Calendar.DAY_OF_MONTH, 1);
		cFim.set(Calendar.MONTH, mes-1);
		cFim.set(Calendar.YEAR, ano);
		cFim.set(Calendar.DAY_OF_MONTH, cFim.getActualMaximum(Calendar.DAY_OF_MONTH));
		cInicio.set(Calendar.DAY_OF_MONTH, cInicio.getActualMinimum(Calendar.DAY_OF_MONTH));

		query = getEm().createQuery(
				"Select c from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim order by c.dataParcela");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", cInicio.getTime());
		query.setParameter("fim", cFim.getTime());
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<ParcelaReceita> listaParcelaReceitaEntreDatasMovimentacoes2(Date inicio,Date fim, Long codigo) {

		query = getEm().createQuery(
				"Select c from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim order by c.dataParcela");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", inicio);
		query.setParameter("fim", fim);
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<ParcelaReceita> listaParcelaReceitaEntreDatasECategoria(Date inicio,Date fim, Long codigo, Long categoria) {
		query = getEm().createQuery(
				"Select c from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim and c.receita.categoria.codigo = :categoria order by c.dataParcela");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", inicio);
		query.setParameter("fim", fim);
		query.setParameter("categoria", categoria);
		return query.getResultList();
	}
	
	public Double somaByCategoria(Long codigo, Date cInicio, Date cFim, Long categoria) {
		
		query = getEm().createQuery(
				"Select sum(c.valor) from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim and c.receita.categoria.codigo = :categoria and c.compensado = 'Sim'");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", cInicio);
		query.setParameter("fim", cFim);
		query.setParameter("categoria", categoria);
		return (Double) query.getSingleResult();
	}
	
	public Double somaReceitasCompensadas(Long codigo, Date cInicio, Date cFim) {
		
		query = getEm().createQuery(
				"Select sum(c.valor) from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim and c.compensado = 'Sim'");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", cInicio);
		query.setParameter("fim", cFim);
		return (Double) query.getSingleResult();
	}
	
	@SuppressWarnings("unchecked")
	public List<ParcelaReceita> parcelaReceitaDataCategoria(Long codigo, Date cInicio, Date cFim,
			Long categoria) {
		
		query = getEm()
				.createQuery(
						"Select c from ParcelaReceita c where c.usuario.codigo = :codigo and c.dataParcela between :inicio and :fim and c.receita.categoria.codigo = :categoria and c.compensado = 'Sim' order by c.dataParcela");
		query.setParameter("codigo", codigo);
		query.setParameter("inicio", cInicio);
		query.setParameter("fim", cFim);
		query.setParameter("categoria", categoria);
		return  (List<ParcelaReceita>) query.getResultList();
	}
	
	

	
	
	

}
